unit uGetCategories;
interface

uses
  Classes,
  SysUtils,
  Variants,
  XMLDoc,
  DB,
  CommonTypes,
  EbayConnect,
  IdThread,
  uThreadSync,
  IdComponent,
  Forms,
  ActiveX,
  uTypes;

  type

  TGetCategoriesThread =  class(TidThread)
  private
     // Private declarations
     FForm          : TForm;
     FOperationResult : AckCodeType;
     FErrorRecord   : eBayAPIError;
     FEbayTradingConnect : TEbayTradingConnect;
     OpResult       : string;

     FSavedCategoriesCnt : Integer;
     FRxDelta       : Integer;
     FTxDelta       : Integer;
     CatCount : Integer;
  protected
     // Protected declarations
     procedure GetAllCategories;
     procedure WriteEbayApiExceptionLog(E : Exception);
     procedure EbayTradingConnectWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
  public
     // Public declarations
     FDevID         : ShortString;
     FAppID         : ShortString;
     FCertID        : ShortString;
     FToken         : WideString;
     FSiteID        : SiteCodeType;
     FGlobalSiteID  : Global_ID;

     FCategoryVersion : Integer;

     FBasePath      : string;
     FCategory      : TCatRec;
     // Objects visible outside threads
     FSyncObj : TFTSync;
     // methods
     constructor  Create(Form: TForm);
     destructor Destroy; override;
     procedure Run; override;
  end;

implementation

uses XMLIntf, HotLog;

{ TGetCategoriesThread }

constructor TGetCategoriesThread.Create(Form: TForm);
begin
  inherited Create(true);
  FForm := Form;
  FreeOnTerminate := True;
  FSyncObj := TFTSync.Create;
  FSyncObj.FThread := Self;
end;

destructor TGetCategoriesThread.Destroy;
begin
  inherited;
end;

procedure TGetCategoriesThread.Run;
var hr: HRESULT;
begin
  inherited;
  try
    hr := CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
    FEbayTradingConnect := TEbayTradingConnect.Create(nil);
    with FEbayTradingConnect do begin
      Host := 'api.ebay.com';
      ServiceURL := 'https://api.ebay.com/ws/api.dll';
      SSLCertFile := 'test_b_crt.pem';
      SSLKeyFile := 'test_b_key.pem';
      SSLRootCertFile := 'test_b_ca.pem';
      SSLPassword := 'aaaa';
      SiteID := FSiteID;
      AppID := FAppID;
      DevID := FDevID;
      CertID := FCertID;
      Token := FToken;
      OnWork := EbayTradingConnectWork;
    end;
    GetAllCategories;
  finally
    FEbayTradingConnect.Free;
    CoUninitialize;
  end;
  //SplashScreen.btn1.Click;
  Stop;
end;

procedure TGetCategoriesThread.GetAllCategories;
var Request, Response : TMemoryStream;
    CXMLDoc : TXMLDocument;
    i : Integer;
    CatNode : IXMLNode;
    TMPStringList : TStringList;
begin
  try
    Request:=TMemoryStream.Create;
    Response:=TMemoryStream.Create;
    CXMLDoc := TXMLDocument.Create(FForm);
    TMPStringList := TStringList.Create;
    TMPStringList.LoadFromFile(FBasePath+'\StoredXML\GetCategories.xml');
    i := FEbayTradingConnect.GetSiteIDNum(FSiteID);
    TMPStringList.Text := StringReplace(TMPStringList.Text,'#CSID',IntToStr(i),[]);
    //Format(TMPStringList.Text,[i]);
    TMPStringList.SaveToStream(Request);
    Request.Seek(0,soFromBeginning);
    try
      hLog.Add('{hms} Getcategories Request Start');
      FRxDelta := 0;
      FTxDelta := 0;
      FEbayTradingConnect.ExecuteRequest(Request,Response);
      hLog.Add('{hms}Getcategories Response received');
      FSyncObj.IncApiUsage;
    except
      on E : Exception do WriteEbayApiExceptionLog(E);
    end;
    Response.Seek(0,soFromBeginning);
    CXMLDoc.XML.LoadFromStream(Response);
    CXMLDoc.Active := True;
    //CXMLDoc.SaveToFile('GetCatRes.xml');
    OpResult := CXMLDoc.DocumentElement.ChildNodes.FindNode('Ack').NodeValue;
    if OpResult = 'Success' then
    try
      FCategoryVersion := CXMLDoc.DocumentElement.ChildNodes.Nodes['CategoryVersion'].NodeValue;
      CatCount := CXMLDoc.DocumentElement.ChildNodes.Nodes['CategoryArray'].ChildNodes.Count;
      FCategory.CatCount := CatCount;
      FCategory.FGlobalSiteID := FGlobalSiteID;
      hLog.Add(Format('{hms} Categories downloaded - %s : %d ',[OpResult,CatCount]));
      if CatCount >0 then begin
        FSavedCategoriesCnt := 0;
        for i :=0 to CatCount-1 do
        begin
          CatNode := CXMLDoc.DocumentElement.ChildNodes.Nodes['CategoryArray'].ChildNodes.Get(i);
          FCategory.CategoryID := StrToInt(CatNode.ChildNodes.Nodes['CategoryID'].NodeValue);
          FCategory.CategoryLevel := CatNode.ChildNodes.Nodes['CategoryLevel'].NodeValue;
          FCategory.CategoryName := CatNode.ChildNodes.Nodes['CategoryName'].NodeValue;
          FCategory.CategoryParentID := StrToInt(CatNode.ChildNodes.Nodes['CategoryParentID'].NodeValue);
          if FCategory.CategoryLevel = 1 then FCategory.CategoryParentID := -1;
          if CatNode.ChildNodes.Nodes['LeafCategory']<> nil then
            if CatNode.ChildNodes.Nodes['LeafCategory'].NodeValue = 'true'
              then FCategory.LeafCategory := true
              else FCategory.LeafCategory := false
          else FCategory.LeafCategory := null;
          inc(FSavedCategoriesCnt);
          FCategory.SavedCategoriesCnt := FSavedCategoriesCnt;
          FSyncObj.SaveCategory;
        end;
        hLog.Add(Format('{hms} Categories Saved - %d',[FSavedCategoriesCnt]));
      end;
    except
      on E : Exception do  hLog.AddException(E,'Save database GetCategories',[]);
    end
    else hLog.Add(Format('{hms} Categories downloaded - %s',[OpResult]));
    CXMLDoc.Active := false;
  finally
    if CXMLDoc <> nil then CXMLDoc.Free;
    if Request <> nil then Request.Free;
    if Response <> nil then Response.Free;
    if TMPStringList <> nil then TMPStringList.Free;
  end;
end;

procedure TGetCategoriesThread.WriteEbayApiExceptionLog(E : Exception);
var fname:string;
begin
  hLog.AddException(E,'GetCategories',[]);
  fname := Format('%s/log/DownloadCategoriesRequest.xml',[FBasePath]);
  hLog.Add('EbayApiException - Request XML saved - '+fname);
  FEbayTradingConnect.RequestXMLText.SaveToFile(fname);
  //for i := 0 to FEbayTradingConnect.RequestXMLText.Count -1 do hLog.Add(FEbayTradingConnect.RequestXMLText.Strings[i]);
  fname := Format('%s/log/DownloadCategoriesResponse.xml',[FBasePath]);
  hLog.Add('EbayApiException -  Response XML saved - '+fname);
  FEbayTradingConnect.ResponseXMLText.SaveToFile(fname);
  //for i := 0 to FEbayTradingConnect.ResponseXMLText.Count -1 do hLog.Add(FEbayTradingConnect.ResponseXMLText.Strings[i]);
end;

procedure TGetCategoriesThread.EbayTradingConnectWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
begin
  case AWorkMode of
  wmRead  : begin
    FSyncObj.OnHttpWork(AWorkMode,AWorkCount-FRxDelta);
    FRxDelta := AWorkCount;
  end;
  wmWrite : begin
    FSyncObj.OnHttpWork(AWorkMode,AWorkCount-FTxDelta);
    FTxDelta := AWorkCount;
  end;
  end;
end;

end.

{
 'update Sites set Version = 96 , LastUpdated = ''08.11.2010 0:09:21'' where GlobalSiteID = ''EBAY_US'''#$D#$A
}
